-
Notifications
You must be signed in to change notification settings - Fork 5.5k
new ticketsauce actions and source #18787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
new ticketsauce actions and source #18787
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified. |
WalkthroughAdds multiple new integrations and actions: Ticketsauce (app client methods, actions, polling "New Event" source, fixtures, package bump), Airweave (app client methods, many actions, README, package bump), several new simple app descriptors (coinapi, copicake, cronly, topdesk), and Microsoft Teams version bumps and a message endpoint path fix. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Action as "Ticketsauce Action"
participant App as "Ticketsauce App"
participant API as "Ticketsauce API"
Note right of Action: action.run({ $ })
Action->>App: call listEvents/getEventDetails/listOrders/getOrderDetails/getTicketCheckinIds($, { ... })
App->>API: HTTP GET (via _makeRequest / axios)
API-->>App: JSON response
App-->>Action: return response
sequenceDiagram
autonumber
participant Source as "Ticketsauce New Event Source"
participant DB as "DB (persistence)"
participant App as "Ticketsauce App"
participant Emit as "Emitter"
Source->>DB: _getLastCreated()
DB-->>Source: lastCreated
Source->>App: listEvents(params)
App-->>Source: events[]
Source->>Source: filter by created_after, sort asc, apply maxResults
Source->>DB: _setLastCreated(newLastCreated) when new events
loop for each new event
Source->>Emit: $emit(event, meta)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (8)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (6)
🧰 Additional context used🧠 Learnings (1)📚 Learning: 2025-01-29T22:59:38.825Z
Applied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (1)
components/ticketsauce/sources/new-event/new-event.mjs (1)
79-88
: Simplify the lastCreated update logic.The current implementation searches through all events to find the most recent created date, but since
newEvents
contains only events created afterlastCreated
, the most recent event innewEvents
already represents the new maximum.Apply this diff to simplify:
// Update last created date if we have new events if (newEvents.length > 0) { - // Find the most recent created date - const mostRecentEvent = events.reduce((latest, current) => - Date.parse(current.Event.created) > Date.parse(latest.Event.created) - ? current - : latest - ); + // Get the most recent event from newEvents (last in sorted array) + const mostRecentEvent = newEvents[newEvents.length - 1]; this._setLastCreated(mostRecentEvent.Event.created); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
components/ticketsauce/actions/get-event-details/get-event-details.mjs
(1 hunks)components/ticketsauce/actions/get-events/get-events.mjs
(1 hunks)components/ticketsauce/actions/get-order-details/get-order-details.mjs
(1 hunks)components/ticketsauce/actions/get-orders/get-orders.mjs
(1 hunks)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs
(1 hunks)components/ticketsauce/package.json
(2 hunks)components/ticketsauce/sources/new-event/new-event.mjs
(1 hunks)components/ticketsauce/sources/new-event/test-event.mjs
(1 hunks)components/ticketsauce/ticketsauce.app.mjs
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (2)
components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(83-98)components/ticketsauce/actions/get-orders/get-orders.mjs (1)
params
(131-147)
components/ticketsauce/sources/new-event/new-event.mjs (1)
components/ticketsauce/ticketsauce.app.mjs (1)
events
(12-15)
components/ticketsauce/actions/get-events/get-events.mjs (2)
components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
params
(53-56)components/ticketsauce/actions/get-orders/get-orders.mjs (1)
params
(131-147)
components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(83-98)
components/ticketsauce/actions/get-orders/get-orders.mjs (3)
components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
params
(53-56)components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(83-98)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (1)
params
(48-51)
components/ticketsauce/ticketsauce.app.mjs (5)
components/ticketsauce/sources/new-event/new-event.mjs (1)
events
(50-58)components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
params
(53-56)components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(83-98)components/ticketsauce/actions/get-orders/get-orders.mjs (1)
params
(131-147)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (1)
params
(48-51)
🪛 GitHub Actions: Components Checks
components/ticketsauce/package.json
[error] 1-1: pnpm install failed due to frozen-lockfile. The lockfile is not up to date with package.json. Run 'pnpm install' without --frozen-lockfile or update the lockfile. Specifiers in the lockfile ({}) don't match specs in package.json ({"@pipedream/platform":"^3.1.0"}).
🪛 GitHub Actions: Pull Request Checks
components/ticketsauce/package.json
[error] 1-1: pnpm install failed due to frozen-lockfile: pnpm-lock.yaml is not up to date with package.json. Specifiers in the lockfile don't match specs in package.json ("@pipedream/platform":"^3.1.0"). Run 'pnpm install --no-frozen-lockfile' or update the lockfile.
[error] 1-1: Dependency specifier mismatch detected in lockfile vs package.json for @pipedream/platform (^3.1.0).
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: pnpm publish
🔇 Additional comments (3)
components/ticketsauce/actions/get-order-details/get-order-details.mjs (1)
1-48
: LGTM!The action structure is well-organized with appropriate propDefinitions for dynamic option loading, and the implementation correctly retrieves order details.
components/ticketsauce/sources/new-event/test-event.mjs (1)
1-47
: LGTM!The test fixture provides appropriate sample data for the New Event source.
components/ticketsauce/sources/new-event/new-event.mjs (1)
1-105
: Verify whether the Ticketsauce/events
endpoint supports or requires pagination.The concern is valid:
listEvents
is called without pagination parameters in new-event.mjs, get-events.mjs, and propDefinitions, while other API calls in the same integration (e.g.,listOrders
) explicitly useper_page
andpage
. If the/events
endpoint returns paginated results, only the first page will be fetched, causing events beyond the first page to be missed.However, this appears to be a consistent pattern across the integration, suggesting either the endpoint returns all results by default or there's a shared gap. Consult the Ticketsauce API documentation or test the endpoint to confirm whether pagination is needed. If required, add pagination parameters (e.g.,
per_page
and pagination loop logic) to thelistEvents
calls.Regarding deduplication: the
dedupe: "unique"
strategy combined with eventid
andlastCreated
tracking should correctly prevent duplicates across runs, assuming event IDs are unique.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (7)
components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (2)
38-50
: Use integer props + bounds for pagination params; avoid sending strings.Define perPage/page as integer with min/max, and send numbers to the API.
@@ - perPage: { - type: "string", + perPage: { + type: "integer", label: "Per Page", description: "How many results to retrieve (per page). Max 5000.", optional: true, + default: 100, + min: 1, + max: 5000, }, @@ - page: { - type: "string", + page: { + type: "integer", label: "Page", description: "Which page to return. For example, if per_page is 20, and page is 3, the results would show 41-60.", optional: true, - default: "1", + default: 1, + min: 1, }, @@ - const params = { - per_page: this.perPage, - page: this.page, - }; + const params = { + per_page: this.perPage, + page: this.page, + };Also applies to: 52-56
52-61
: Optionally add “paginate all” support to meet the pagination guideline.Add a boolean paginateAll to fetch all pages in one run; otherwise keep current single-page behavior. As per component checklist.
@@ props: { @@ + paginateAll: { + type: "boolean", + label: "Paginate All", + description: "If true, fetches all pages of check-in IDs.", + optional: true, + default: false, + }, @@ async run() { - const params = { + const params = { per_page: this.perPage, page: this.page, }; - return this.ticketsauce.getTicketCheckinIds({ - eventId: this.eventId, - params, - }); + if (!this.paginateAll) { + return this.ticketsauce.getTicketCheckinIds({ eventId: this.eventId, params }); + } + const all = []; + let page = params.page || 1; + while (true) { + const res = await this.ticketsauce.getTicketCheckinIds({ eventId: this.eventId, params: { ...params, page } }); + const items = Array.isArray(res) ? res : (res?.data ?? []); + all.push(...items); + if (!items.length || (params.per_page && items.length < params.per_page)) break; + page += 1; + } + return all; },Please confirm Ticketsauce’s “Ticket Check-in IDs” endpoint supports per_page/page and whether 5000 is the documented max. If different, we’ll adjust min/max and loop stop conditions.
components/ticketsauce/actions/get-events/get-events.mjs (2)
59-69
: Set explicit defaults to match the descriptions.Descriptions say default sort is date/asc, but props have no defaults. Add them for consistency.
sortBy: { type: "string", label: "Sort By", description: "Which field to sort by. By default ('date'), will sort events by their start date. Other options are 'name' (event name) or 'city' (the city where the event is located).", optional: true, + default: "date", options: [ "date", "name", "city", ], }, @@ sortDir: { type: "string", label: "Sort Direction", description: "Which direction you'd like to sort - either ascending ('asc' - the default) or descending ('desc').", optional: true, + default: "asc", options: [ "asc", "desc", ], },Also applies to: 70-79
87-103
: Avoid sending undefined query keys.Clean the params object before calling the app method to prevent undefined from being sent.
async run() { - const params = { + const paramsRaw = { partner_id: this.partnerId, organization_id: this.organizationId, start_after: this.startAfter, end_before: this.endBefore, active_only: this.activeOnly, privacy_type: this.privacyType, sort_by: this.sortBy, sort_dir: this.sortDir, include_performers: this.includePerformers, }; - - return this.ticketsauce.listEvents({ - params, - }); + const params = Object.fromEntries(Object.entries(paramsRaw).filter(([, v]) => v !== undefined)); + return this.ticketsauce.listEvents({ params }); },components/ticketsauce/actions/get-orders/get-orders.mjs (3)
38-51
: Use integer props + bounds for perPage/page.Ensure numeric types and enforce API limits (max 500 as described).
perPage: { - type: "string", + type: "integer", label: "Per Page", description: "How many results to retrieve (per page). Max 500.", optional: true, - default: "100", + default: 100, + min: 1, + max: 500, }, page: { - type: "string", + type: "integer", label: "Page", description: "Which page to return. For example, if per_page is 20, and page is 3, the results would show 41-60.", optional: true, - default: "1", + default: 1, + min: 1, },
136-156
: Strip undefined query params before request.Prevents sending dead/undefined keys; keeps requests clean.
- const params = { + const paramsRaw = { per_page: this.perPage, page: this.page, q: this.q, return_questionnaires: this.returnQuestionnaires, return_tickets: this.returnTickets, return_line_item_fees: this.returnLineItemFees, ordered_after: this.orderedAfter, ordered_before: this.orderedBefore, modified_after: this.modifiedAfter, modified_before: this.modifiedBefore, sort_by: this.sortBy, sort_dir: this.sortDir, total_above: this.totalAbove, total_below: this.totalBelow, }; + const params = Object.fromEntries(Object.entries(paramsRaw).filter(([, v]) => v !== undefined)); return this.ticketsauce.listOrders({ eventId: this.eventId, params, });
38-75
: Optional: add paginateAll to fetch all pages in one action.Meets the “handle pagination” checklist; keeps current behavior default.
@@ props: { @@ + paginateAll: { + type: "boolean", + label: "Paginate All", + description: "If true, fetches all pages of orders.", + optional: true, + default: false, + }, @@ async run() { - const paramsRaw = { + const paramsRaw = { per_page: this.perPage, page: this.page, @@ - const params = Object.fromEntries(Object.entries(paramsRaw).filter(([, v]) => v !== undefined)); - - return this.ticketsauce.listOrders({ - eventId: this.eventId, - params, - }); + const params = Object.fromEntries(Object.entries(paramsRaw).filter(([, v]) => v !== undefined)); + if (!this.paginateAll) { + return this.ticketsauce.listOrders({ eventId: this.eventId, params }); + } + const all = []; + let page = params.page || 1; + while (true) { + const res = await this.ticketsauce.listOrders({ eventId: this.eventId, params: { ...params, page } }); + const items = Array.isArray(res) ? res : (res?.data ?? []); + all.push(...items); + if (!items.length || (params.per_page && items.length < params.per_page)) break; + page += 1; + } + return all; },Confirm Ticketsauce’s “Orders” endpoint page size limit (doc says 500 here). If different, update max.
Also applies to: 100-121, 135-157
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (5)
components/ticketsauce/actions/get-event-details/get-event-details.mjs
(1 hunks)components/ticketsauce/actions/get-events/get-events.mjs
(1 hunks)components/ticketsauce/actions/get-order-details/get-order-details.mjs
(1 hunks)components/ticketsauce/actions/get-orders/get-orders.mjs
(1 hunks)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- components/ticketsauce/actions/get-order-details/get-order-details.mjs
- components/ticketsauce/actions/get-event-details/get-event-details.mjs
🧰 Additional context used
🧬 Code graph analysis (3)
components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (2)
components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(88-98)components/ticketsauce/actions/get-orders/get-orders.mjs (1)
params
(136-151)
components/ticketsauce/actions/get-events/get-events.mjs (3)
components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
params
(58-61)components/ticketsauce/actions/get-orders/get-orders.mjs (1)
params
(136-151)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (1)
params
(53-56)
components/ticketsauce/actions/get-orders/get-orders.mjs (3)
components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
params
(58-61)components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(88-98)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (1)
params
(53-56)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: pnpm publish
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (1)
components/ticketsauce/actions/get-events/get-events.mjs (1)
14-27
: Confirm whether the Events API supports pagination; add props if so.If the endpoint accepts per_page/page, expose them (integer with min/max) and forward to params to align with the pagination checklist. If not, ignore.
Also applies to: 87-98
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
components/ticketsauce/sources/new-event/new-event.mjs (1)
78-84
: Consider clarifying the cursor update logic.The logic correctly updates
lastCreated
to the most recent event from the fullevents
array (not justnewEvents
), which properly advances the cursor. However, the conditionif (newEvents.length > 0)
might be clearer as a comment explaining that we only update the cursor when we've emitted new events.Consider adding a clarifying comment:
- // Update last created date if we have new events if (newEvents.length > 0) { + // Update cursor to the most recent event from all fetched events // Find the most recent created date const mostRecentEvent = events.reduce((latest, current) =>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
components/ticketsauce/package.json
(2 hunks)components/ticketsauce/sources/new-event/new-event.mjs
(1 hunks)components/ticketsauce/ticketsauce.app.mjs
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
components/ticketsauce/sources/new-event/new-event.mjs (1)
components/ticketsauce/ticketsauce.app.mjs (1)
events
(14-17)
components/ticketsauce/ticketsauce.app.mjs (5)
components/ticketsauce/sources/new-event/new-event.mjs (1)
events
(50-58)components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
params
(58-61)components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(88-98)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (1)
params
(53-56)components/ticketsauce/actions/get-orders/get-orders.mjs (1)
params
(136-151)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
- GitHub Check: Lint Code Base
- GitHub Check: pnpm publish
🔇 Additional comments (7)
components/ticketsauce/package.json (1)
1-18
: LGTM!The version bump and dependency addition are appropriate for the new components being introduced. The past lockfile issue has been addressed.
components/ticketsauce/sources/new-event/new-event.mjs (3)
4-32
: LGTM!The source metadata, props, and timer configuration are well-structured. The 1-hour interval appropriately matches the API cache behavior mentioned in the comment.
34-46
: LGTM!The cursor management and metadata generation helpers follow standard patterns and integrate well with the db service.
93-100
: LGTM!The deploy hook with a 25-event limit and the unlimited run method follow the standard polling source pattern.
components/ticketsauce/ticketsauce.app.mjs (3)
31-71
: LGTM!The
orderId
propDefinition correctly implements pagination with context tracking and appropriate handling of empty results. The label format provides helpful order identification.
74-85
: LGTM!The
_makeRequest
helper follows the standard pattern for API integration, properly handling authentication and parameter merging.
86-134
: LGTM!The API helper methods are well-structured and correctly delegate to
_makeRequest
. Each method appropriately handles its parameters and constructs the correct API paths.
eventId: { | ||
type: "string", | ||
label: "Event", | ||
description: "Select an event", | ||
async options({ | ||
partnerId, organizationId, | ||
}) { | ||
const events = await this.listEvents({ | ||
partnerId, | ||
organizationId, | ||
}); | ||
|
||
if (!events?.length) { | ||
return []; | ||
} | ||
|
||
const options = events.map((eventData) => ({ | ||
label: `${eventData.Event.name} - ${eventData.Event.city} (${eventData.Event.start})`, | ||
value: eventData.Event.id, | ||
})); | ||
|
||
return options; | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Implement pagination for event options.
The eventId
propDefinition fetches all events without pagination, which could fail to load all available events if the dataset is large. Per the component guidelines: "Handle pagination for API requests to ensure all data/events are processed."
Apply a similar pagination pattern to the orderId
propDefinition (lines 31-71):
async options({
- partnerId, organizationId,
+ partnerId, organizationId, prevContext,
}) {
const events = await this.listEvents({
partnerId,
organizationId,
+ params: {
+ per_page: 100,
+ page: prevContext?.page || 0,
+ },
});
if (!events?.length) {
- return [];
+ return prevContext?.page > 0
+ ? {
+ options: [],
+ context: {},
+ }
+ : [];
}
const options = events.map((eventData) => ({
label: `${eventData.Event.name} - ${eventData.Event.city} (${eventData.Event.start})`,
value: eventData.Event.id,
}));
- return options;
+ return {
+ options,
+ context: {
+ page: (prevContext?.page || 0) + 1,
+ },
+ };
},
Note: Verify that the Ticketsauce API supports per_page
and page
parameters for the /events
endpoint.
🏁 Script executed:
#!/bin/bash
# Verify if the Ticketsauce API documentation mentions pagination parameters for the events endpoint
rg -i "per_page|page|pagination" --type md -C 3
Length of output: 191188
🏁 Script executed:
#!/bin/bash
# Examine the ticketsauce component to verify pagination implementation
# First, find the ticketsauce component file
find . -name "ticketsauce.app.mjs" -o -name "ticketsauce*.mjs" | head -20
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Get the ticketsauce component content to verify pagination claims
cat components/ticketsauce/ticketsauce.app.mjs | head -150
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Check if there's API documentation or examples for ticketsauce
find components/ticketsauce -type f \( -name "*.md" -o -name "*.js" -o -name "*.mjs" \) | head -20
Length of output: 490
🏁 Script executed:
#!/bin/bash
# Look for any common API integration files to understand pagination patterns
rg -l "per_page|prevContext" --type mjs components/ | head -10
Length of output: 27
🏁 Script executed:
#!/bin/bash
# Search for the listEvents method specifically in ticketsauce
rg -A 20 "listEvents\s*\(" components/ticketsauce/
Length of output: 4957
🏁 Script executed:
#!/bin/bash
# Search for orderId propDefinition in ticketsauce to compare implementation
rg -A 30 "orderId.*propDefinition\|orderId\s*:\s*\{" components/ticketsauce/
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Check the complete file structure
wc -l components/ticketsauce/ticketsauce.app.mjs && head -200 components/ticketsauce/ticketsauce.app.mjs
Length of output: 3076
🏁 Script executed:
#!/bin/bash
# Look for any Ticketsauce-specific documentation or README
find components/ticketsauce -name "README*" -o -name "*.md" | xargs cat 2>/dev/null || echo "No README found"
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Search for pagination patterns in the codebase to see if prevContext is the standard
rg -B 5 -A 15 'prevContext.*page' components/ --type mjs | head -80
Length of output: 27
🏁 Script executed:
#!/bin/bash
# Specifically check orderId implementation in ticketsauce
ast-grep --pattern 'orderId.*:.*{
$$$
async options($_) {
$$$
}
$$$
}'
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Get the full ticketsauce.app.mjs to understand the complete context
cat components/ticketsauce/ticketsauce.app.mjs
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Search for API method to understand pagination support
rg -B 5 -A 20 "_makeRequest|getEventDetails|listEvents" components/ticketsauce/ticketsauce.app.mjs | head -100
Length of output: 2031
🏁 Script executed:
#!/bin/bash
# Check GitHub or external documentation reference
rg -i "ticketsauce.*api|api.*ticketsauce" components/ticketsauce/ --type md
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Look at the prop definitions more carefully
rg -B 2 -A 50 "propDefinitions\s*=" components/ticketsauce/ticketsauce.app.mjs | head -150
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Final check: examine lines 7-30 and 31-71 as mentioned in review
sed -n '1,150p' components/ticketsauce/ticketsauce.app.mjs
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Check if orderId even exists and how pagination is implemented there
grep -n "orderId" components/ticketsauce/ticketsauce.app.mjs | head -20
Length of output: 101
🏁 Script executed:
#!/bin/bash
# Look for the entire propDefinitions section
sed -n '/propDefinitions/,/^ [a-zA-Z]/p' components/ticketsauce/ticketsauce.app.mjs | head -200
Length of output: 1581
🏁 Script executed:
#!/bin/bash
# Search broadly for pagination patterns in prop definitions
rg -B 3 -A 20 "async options.*partnerId.*organizationId" components/ --type mjs | head -100
Length of output: 27
🏁 Script executed:
#!/bin/bash
# Check if the Ticketsauce API endpoint documentation is mentioned anywhere
rg -i "event.*list|list.*event" components/ticketsauce/ --type md --type mjs | grep -i "per_page\|page\|limit\|offset"
Length of output: 27
🏁 Script executed:
#!/bin/bash
# Get just the file with line numbers to see exact structure
cat -n components/ticketsauce/ticketsauce.app.mjs | head -180
Length of output: 3981
🏁 Script executed:
#!/bin/bash
# Check all files in ticketsauce directory
ls -la components/ticketsauce/
Length of output: 379
🏁 Script executed:
#!/bin/bash
# Get comprehensive view of the app.mjs file
head -300 components/ticketsauce/ticketsauce.app.mjs | tail -150
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Search for the actual line numbers mentioned (7-30 and 31-71)
sed -n '1,80p' components/ticketsauce/ticketsauce.app.mjs | cat -n
Length of output: 2463
🏁 Script executed:
#!/bin/bash
# Final attempt to get the complete structure to understand pagination
python3 << 'EOF'
import json
try:
with open('components/ticketsauce/ticketsauce.app.mjs', 'r') as f:
content = f.read()
# Print first 1000 characters with line numbers
for i, line in enumerate(content.split('\n')[:120], 1):
print(f"{i:3d}: {line}")
except Exception as e:
print(f"Error: {e}")
EOF
Length of output: 3304
🏁 Script executed:
#!/bin/bash
# Look at the entire component to understand its structure
wc -l components/ticketsauce/ticketsauce.app.mjs
cat components/ticketsauce/ticketsauce.app.mjs | head -250
Length of output: 3076
🏁 Script executed:
#!/bin/bash
# Search for pagination in this specific component more thoroughly
rg "page|pagination|per_page|prevContext|offset|limit" components/ticketsauce/ -A 2 -B 2
Length of output: 10360
🏁 Script executed:
#!/bin/bash
# Check if the component has actions or methods that show how the API works
find components/ticketsauce -type f -name "*.mjs" -o -name "*.js" | xargs ls -la
Length of output: 882
🏁 Script executed:
#!/bin/bash
# Look at test files or examples if they exist
find components/ticketsauce -name "*test*" -o -name "*example*" -o -name "*action*" | xargs cat 2>/dev/null | head -200
Length of output: 1485
🏁 Script executed:
#!/bin/bash
# Get the actual entire file now
cat components/ticketsauce/ticketsauce.app.mjs
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Simple check: does the file exist and get its size
stat components/ticketsauce/ticketsauce.app.mjs 2>&1 && echo "---" && wc -l components/ticketsauce/ticketsauce.app.mjs
Length of output: 42
🏁 Script executed:
#!/bin/bash
# Use python to read and display the file safely
python3 -c "
with open('components/ticketsauce/ticketsauce.app.mjs', 'r') as f:
lines = f.readlines()
for i, line in enumerate(lines[:200], 1):
print(f'{i:4d}: {line}', end='')
"
Length of output: 3845
🏁 Script executed:
#!/bin/bash
# Double-check the component exists and examine its key sections
file components/ticketsauce/ticketsauce.app.mjs && echo "---FILE EXISTS---" && head -250 components/ticketsauce/ticketsauce.app.mjs
Length of output: 42
🏁 Script executed:
#!/bin/bash
# If the direct approach fails, try finding similar components with working pagination
find components -name "*.app.mjs" -type f | xargs grep -l "prevContext" | head -5 | xargs -I {} sh -c 'echo "=== {} ===" && grep -A 30 "async options" {}'
Length of output: 12766
🏁 Script executed:
#!/bin/bash
# Look at how other components implement pagination to validate the pattern
rg -A 40 "prevContext\?\s*\." components --type mjs | head -150
Length of output: 27
🏁 Script executed:
#!/bin/bash
# Check if orderid exists in the file at all
grep -c "orderId\|eventId" components/ticketsauce/ticketsauce.app.mjs || echo "Pattern not found"
Length of output: 2
🏁 Script executed:
#!/bin/bash
# Final comprehensive check
python3 << 'EOF'
with open('components/ticketsauce/ticketsauce.app.mjs', 'r') as f:
content = f.read()
# Show file length
print(f"Total lines: {len(content.split(chr(10)))}")
print("\n--- FIRST 300 LINES ---\n")
lines = content.split('\n')
for i, line in enumerate(lines[:300], 1):
print(f"{i:4}: {line}")
EOF
Length of output: 3895
🏁 Script executed:
#!/bin/bash
# Check Ticketsauce API docs if available in repo
find . -name "*ticketsauce*" -type f | head -20
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Last resort: use head with explicit count
head -n 400 components/ticketsauce/ticketsauce.app.mjs
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Check all mjs files in the component directory
find components/ticketsauce -name "*.mjs" | xargs wc -l
Length of output: 550
🏁 Script executed:
#!/bin/bash
# Display directory structure
ls -R components/ticketsauce/
Length of output: 649
🏁 Script executed:
#!/bin/bash
# Most direct approach - read the file
cat components/ticketsauce/ticketsauce.app.mjs 2>&1 | head -400
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Check if orderId or eventId exists and list line numbers
grep -n "orderId\|eventId\|listEvents\|getOrderDetails\|getEventDetails" components/ticketsauce/ticketsauce.app.mjs | head -30
Length of output: 521
🏁 Script executed:
#!/bin/bash
# Get the section between propDefinitions and the methods
awk '/propDefinitions/,/^ [a-zA-Z_].*\(/ {print NR": "$0}' components/ticketsauce/ticketsauce.app.mjs | head -200
Length of output: 3486
🏁 Script executed:
#!/bin/bash
# Simple line extraction
awk 'NR>=1 && NR<=250 {print NR": "$0}' components/ticketsauce/ticketsauce.app.mjs
Length of output: 3601
🏁 Script executed:
#!/bin/bash
# Try to find the propDefinitions section more carefully
sed -n '1,200p' components/ticketsauce/ticketsauce.app.mjs | nl
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Use a Python approach to handle the file robustly
python3 << 'PYTHON'
try:
with open('components/ticketsauce/ticketsauce.app.mjs') as f:
for i, line in enumerate(f, 1):
if i <= 300:
print(f"{i:4}: {line.rstrip()}")
else:
break
except FileNotFoundError:
print("File not found")
except Exception as e:
print(f"Error: {e}")
PYTHON
Length of output: 3845
🏁 Script executed:
#!/bin/bash
# Extract propDefinitions section more robustly
python3 << 'PYTHON'
import re
try:
with open('components/ticketsauce/ticketsauce.app.mjs') as f:
content = f.read()
# Find propDefinitions
match = re.search(r'propDefinitions\s*=\s*\{(.*?)\n \}', content, re.DOTALL)
if match:
prop_section = match.group(1)
lines = prop_section.split('\n')
for i, line in enumerate(lines[:150], 1):
print(f"{i:4}: {line}")
else:
print("propDefinitions not found. Showing first 300 lines:")
for i, line in enumerate(content.split('\n')[:300], 1):
print(f"{i:4}: {line}")
except Exception as e:
print(f"Error: {e}")
PYTHON
Length of output: 3904
🏁 Script executed:
#!/bin/bash
# Check if there's an orderId property that shows pagination
python3 << 'PYTHON'
import re
try:
with open('components/ticketsauce/ticketsauce.app.mjs') as f:
content = f.read()
# Look for both eventId and orderId
if 'orderId' in content:
print("orderId FOUND - extracting context:")
idx = content.find('orderId')
print(content[max(0, idx-100):min(len(content), idx+500)])
print("\n---\n")
if 'eventId' in content:
print("eventId FOUND - extracting context:")
idx = content.find('eventId')
print(content[max(0, idx-100):min(len(content), idx+500)])
if 'orderId' not in content and 'eventId' not in content:
print("Neither orderId nor eventId found. First 500 chars:")
print(content[:500])
except Exception as e:
print(f"Error: {e}")
PYTHON
Length of output: 1279
🏁 Script executed:
#!/bin/bash
# Get comprehensive view using tail and head
total=$(wc -l < components/ticketsauce/ticketsauce.app.mjs)
echo "Total lines: $total"
head -n 300 components/ticketsauce/ticketsauce.app.mjs
Length of output: 3046
🏁 Script executed:
#!/bin/bash
# Verify the component file is readable
test -r components/ticketsauce/ticketsauce.app.mjs && echo "File is readable" || echo "File not readable"
ls -la components/ticketsauce/ticketsauce.app.mjs
cat components/ticketsauce/ticketsauce.app.mjs
Length of output: 3138
🏁 Script executed:
#!/bin/bash
# Extract and display the propDefinitions
rg -A 250 "propDefinitions\s*=" components/ticketsauce/ticketsauce.app.mjs | head -300
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Just dump the whole file with line numbers
nl -ba components/ticketsauce/ticketsauce.app.mjs | head -300
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Use sed to extract lines 1-300
sed -n '1,300p' components/ticketsauce/ticketsauce.app.mjs | cat -n
Length of output: 3981
🏁 Script executed:
#!/bin/bash
# Use awk to display with line numbers
awk '{print NR": "$0}' components/ticketsauce/ticketsauce.app.mjs | head -300
Length of output: 3601
🏁 Script executed:
#!/bin/bash
# Try a basic cat with explicit line selection
cat components/ticketsauce/ticketsauce.app.mjs | sed -n '1,300p' | nl
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Ultimate fallback - use less then pipe through sed
head -300 < components/ticketsauce/ticketsauce.app.mjs | nl -ba -v 1
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Read using python line by line
python3 << 'PYEOF'
with open('components/ticketsauce/ticketsauce.app.mjs', 'r', encoding='utf-8', errors='ignore') as f:
for line_num, line in enumerate(f, 1):
if line_num <= 300:
print(f"{line_num:4d}| {line}", end='')
PYEOF
Length of output: 3845
🏁 Script executed:
#!/bin/bash
# Check the actual structure by looking at the propDefinitions key
grep -n "propDefinitions" components/ticketsauce/ticketsauce.app.mjs && sed -n '1,150p' components/ticketsauce/ticketsauce.app.mjs
Length of output: 3052
🏁 Script executed:
#!/bin/bash
# Look at both patterns in the review - orderId and eventId
rg "orderId|eventId" components/ticketsauce/ticketsauce.app.mjs -B 5 -A 15
Length of output: 1769
🏁 Script executed:
#!/bin/bash
# Extract the exact lines mentioned in the review (7-30 and 31-71)
echo "=== Lines 1-80 of ticketsauce.app.mjs ===" && sed -n '1,80p' components/ticketsauce/ticketsauce.app.mjs && echo "" && echo "=== Line count ===" && wc -l components/ticketsauce/ticketsauce.app.mjs
Length of output: 2012
🏁 Script executed:
#!/bin/bash
# Final attempt: read entire file and pipe through tools
cat components/ticketsauce/ticketsauce.app.mjs | head -150
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Check if code is readable and get a meaningful snippet
file components/ticketsauce/ticketsauce.app.mjs && head -c 2000 components/ticketsauce/ticketsauce.app.mjs
Length of output: 42
🏁 Script executed:
#!/bin/bash
# Try expanding the view
expand components/ticketsauce/ticketsauce.app.mjs | head -300
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Most basic approach that should work
strings components/ticketsauce/ticketsauce.app.mjs | head -300
Length of output: 45
🏁 Script executed:
#!/bin/bash
# Try with iconv if encoding issues
iconv -f UTF-8 -t UTF-8 components/ticketsauce/ticketsauce.app.mjs 2>/dev/null | head -250 || cat components/ticketsauce/ticketsauce.app.mjs | head -250
Length of output: 0
🏁 Script executed:
#!/bin/bash
# Last resort: use od or hexdump to check file integrity then cat
od -c components/ticketsauce/ticketsauce.app.mjs | head -20 && echo "---" && cat components/ticketsauce/ticketsauce.app.mjs | head -200
Length of output: 3074
🏁 Script executed:
#!/bin/bash
# Simplest possible: just read it
cat < components/ticketsauce/ticketsauce.app.mjs | head -n 200
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Check file permissions and try reading
stat components/ticketsauce/ticketsauce.app.mjs
timeout 5 cat components/ticketsauce/ticketsauce.app.mjs | head -n 250
Length of output: 88
🏁 Script executed:
#!/bin/bash
# Read the full file into a variable and extract
content=$(cat components/ticketsauce/ticketsauce.app.mjs 2>&1)
echo "$content" | head -200
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Use find to verify the file and then read it
find . -path "*ticketsauce/ticketsauce.app.mjs" -exec head -200 {} \;
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Final comprehensive script
ls -la components/ticketsauce/
echo "---"
echo "File type:"
file components/ticketsauce/ticketsauce.app.mjs
echo "---"
echo "Content:"
cat components/ticketsauce/ticketsauce.app.mjs 2>&1 | head -150
Length of output: 3480
🏁 Script executed:
#!/bin/bash
# Verify the ticketsauce component exists and show its structure
if [ -f components/ticketsauce/ticketsauce.app.mjs ]; then
echo "✓ File exists"
head -100 components/ticketsauce/ticketsauce.app.mjs
else
echo "✗ File not found. Checking directory..."
find . -name "*ticketsauce*" -type d
find . -name "*ticketsauce*" -type f | head -10
fi
Length of output: 2291
🏁 Script executed:
#!/bin/bash
# Use process substitution to ensure we can read the file
{ head -250 components/ticketsauce/ticketsauce.app.mjs; } 2>&1
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Check if the component exists in a different location
find components -name "ticketsauce*" -type f
Length of output: 42
🏁 Script executed:
#!/bin/bash
# Use sed to reliably extract content
sed '1,250!d' components/ticketsauce/ticketsauce.app.mjs
Length of output: 51
🏁 Script executed:
#!/bin/bash
# Double check the file with multiple approaches
test -e components/ticketsauce/ticketsauce.app.mjs && head -n 250 components/ticketsauce/ticketsauce.app.mjs || echo "File search:" && find . -name "ticketsauce.app.mjs"
Length of output: 3074
🏁 Script executed:
#!/bin/bash
# Most reliable: use bash read builtin
while IFS= read -r line; do
((n++))
[ $n -le 250 ] && echo "$n: $line"
done < components/ticketsauce/ticketsauce.app.mjs
Length of output: 3601
🏁 Script executed:
#!/bin/bash
# Alternative: use awk with BEGIN to show structure
awk 'BEGIN{n=0} {n++; if(n<=250) print n": "$0}' components/ticketsauce/ticketsauce.app.mjs
Length of output: 3601
🏁 Script executed:
#!/bin/bash
# Final final attempt
(head -n 250 components/ticketsauce/ticketsauce.app.mjs) 2>&1 || (ls components/ticketsauce/ && echo "---" && file components/ticketsauce/ticketsauce.app.mjs)
Length of output: 3029
🏁 Script executed:
#!/bin/bash
# Read file and extract key sections
python3 << 'EOF'
import os
path = 'components/ticketsauce/ticketsauce.app.mjs'
if os.path.exists(path):
with open(path, 'r', encoding='utf-8', errors='replace') as f:
lines = f.readlines()
print(f"Total lines: {len(lines)}\n")
for i, line in enumerate(lines[:250], 1):
print(f"{i:4}: {line.rstrip()}")
else:
print(f"File not found: {path}")
print("Available files:")
for root, dirs, files in os.walk('components/ticketsauce'):
for file in files:
print(f" {os.path.join(root, file)}")
EOF
Length of output: 3863
Implement pagination for eventId propDefinition.
eventId.options currently calls listEvents without pagination — users with many events will get truncated results. Apply the same prevContext / per_page / page pattern used by orderId (eventId: components/ticketsauce/ticketsauce.app.mjs, lines 7–30; listEvents: lines 86–105).
async options({
- partnerId, organizationId,
+ partnerId, organizationId, prevContext,
}) {
const events = await this.listEvents({
partnerId,
organizationId,
+ params: {
+ per_page: 100,
+ page: prevContext?.page || 0,
+ },
});
if (!events?.length) {
- return [];
+ return prevContext?.page > 0
+ ? {
+ options: [],
+ context: {},
+ }
+ : [];
}
const options = events.map((eventData) => ({
label: `${eventData.Event.name} - ${eventData.Event.city} (${eventData.Event.start})`,
value: eventData.Event.id,
}));
- return options;
+ return {
+ options,
+ context: {
+ page: (prevContext?.page || 0) + 1,
+ },
+ };
},
Verify /events accepts per_page/page (other ticketsauce actions use per_page/page for orders/tickets).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
eventId: { | |
type: "string", | |
label: "Event", | |
description: "Select an event", | |
async options({ | |
partnerId, organizationId, | |
}) { | |
const events = await this.listEvents({ | |
partnerId, | |
organizationId, | |
}); | |
if (!events?.length) { | |
return []; | |
} | |
const options = events.map((eventData) => ({ | |
label: `${eventData.Event.name} - ${eventData.Event.city} (${eventData.Event.start})`, | |
value: eventData.Event.id, | |
})); | |
return options; | |
}, | |
}, | |
eventId: { | |
type: "string", | |
label: "Event", | |
description: "Select an event", | |
async options({ | |
partnerId, organizationId, prevContext, | |
}) { | |
const events = await this.listEvents({ | |
partnerId, | |
organizationId, | |
params: { | |
per_page: 100, | |
page: prevContext?.page || 0, | |
}, | |
}); | |
if (!events?.length) { | |
return prevContext?.page > 0 | |
? { | |
options: [], | |
context: {}, | |
} | |
: []; | |
} | |
const options = events.map((eventData) => ({ | |
label: `${eventData.Event.name} - ${eventData.Event.city} (${eventData.Event.start})`, | |
value: eventData.Event.id, | |
})); | |
return { | |
options, | |
context: { | |
page: (prevContext?.page || 0) + 1, | |
}, | |
}; | |
}, | |
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pagination is not supported. "List of Events" endpoint returns all events, users always can filter out data.
List of Events
GET /v2/events
Get a list of all events you own. This data is not only sortable, but can be filtered by a large number of optional parameters. All date/time options should be UTC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sergio-eliot-rodriguez, thank you for clarifying! If the /events
endpoint returns all events without pagination support, then the current implementation is correct. I appreciate you sharing this API behavior detail.
✏️ Learnings added
Learnt from: sergio-eliot-rodriguez
PR: PipedreamHQ/pipedream#18787
File: components/ticketsauce/ticketsauce.app.mjs:7-30
Timestamp: 2025-10-17T06:58:24.566Z
Learning: The TicketSauce "List of Events" API endpoint (GET /v2/events) does not support pagination and returns all events. Users can filter the data using the available query parameters (partner_id, organization_id, etc.) rather than paginating through results.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
Resolves #18366 |
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
components/ticketsauce/actions/get-orders/get-orders.mjs (2)
153-157
: Add an action run summary.Set a concise $summary so users see a helpful message in the UI.
- return this.ticketsauce.listOrders({ + const res = await this.ticketsauce.listOrders({ eventId: this.eventId, params, }); + this.$summary = `Retrieved orders for event ${this.eventId}`; + return res;
38-51
: Use integer types, enforce bounds, and exclude undefined params.The Ticketsauce app helper passes params directly to axios without sanitization or type conversion. Verify the refactor against the Ticketsauce API documentation to confirm the Max 500 per_page limit, then apply these changes:
@@ perPage: { - type: "string", + type: "integer", label: "Per Page", description: "How many results to retrieve (per page). Max 500.", optional: true, - default: "100", + default: 100, + min: 1, + max: 500, }, page: { - type: "string", + type: "integer", label: "Page", description: "Which page to return. For example, if per_page is 20, and page is 3, the results would show 41-60.", optional: true, - default: "1", + default: 1, + min: 1, }, @@ - totalAbove: { - type: "string", + totalAbove: { + type: "integer", label: "Total Above", description: "Return only orders whose order total is greater than this value.", optional: true, }, totalBelow: { - type: "string", + type: "integer", label: "Total Below", description: "Return only orders whose order total is less than this value.", optional: true, }, @@ async run() { - const params = { - per_page: this.perPage, - page: this.page, - q: this.q, - return_questionnaires: this.returnQuestionnaires, - return_tickets: this.returnTickets, - return_line_item_fees: this.returnLineItemFees, - ordered_after: this.orderedAfter, - ordered_before: this.orderedBefore, - modified_after: this.modifiedAfter, - modified_before: this.modifiedBefore, - sort_by: this.sortBy, - sort_dir: this.sortDir, - total_above: this.totalAbove, - total_below: this.totalBelow, - }; + const perPage = Math.min(Number(this.perPage ?? 100), 500); + const page = Math.max(Number(this.page ?? 1), 1); + const params = { + per_page: perPage, + page, + ...(this.q && { q: this.q }), + ...(this.returnQuestionnaires !== undefined && { return_questionnaires: this.returnQuestionnaires }), + ...(this.returnTickets !== undefined && { return_tickets: this.returnTickets }), + ...(this.returnLineItemFees !== undefined && { return_line_item_fees: this.returnLineItemFees }), + ...(this.orderedAfter && { ordered_after: this.orderedAfter }), + ...(this.orderedBefore && { ordered_before: this.orderedBefore }), + ...(this.modifiedAfter && { modified_after: this.modifiedAfter }), + ...(this.modifiedBefore && { modified_before: this.modifiedBefore }), + ...(this.sortBy && { sort_by: this.sortBy }), + ...(this.sortDir && { sort_dir: this.sortDir }), + ...(this.totalAbove !== undefined && { total_above: this.totalAbove }), + ...(this.totalBelow !== undefined && { total_below: this.totalBelow }), + };Also applies to: lines 122-133, 135-151
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
components/ticketsauce/actions/get-orders/get-orders.mjs
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/ticketsauce/actions/get-orders/get-orders.mjs (3)
components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (1)
params
(53-56)components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(88-98)components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
params
(58-61)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
🔇 Additional comments (1)
components/ticketsauce/actions/get-orders/get-orders.mjs (1)
28-37
: Dynamic event selector looks good.Clean use of propDefinition with partnerId/organizationId context to scope event options.
export default { | ||
key: "ticketsauce-get-orders", | ||
name: "Get Orders", | ||
description: "Get a list of orders from the specified event. [See documentation](https://speca.io/ticketsauce/ticketsauce-public-api?key=204000d6bda66da78315e721920f43aa#orders)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Use a stable docs URL (avoid query keys in the link).
The speca URL includes a ?key=...
parameter that may be temporary. Link to the canonical page to prevent future link rot.
🌐 Web query:
What is the canonical public documentation URL for the Ticketsauce Orders endpoint (without a temporary key parameter)?
💡 Result:
Do you mean the TicketSauce API "Orders" documentation page (their public API docs)? If so, please confirm — I couldn't find a clear canonical Orders-docs URL and will search again once you confirm.
I'll perform a more targeted search to find Ticketsauce's official API documentation structure.
Let me search more specifically for Ticketsauce's official developer documentation.
Let me search specifically for information about speca.io and its URL structure.
Update the URL to remove the temporary query parameter.
The ?key=...
parameter is not part of standard Speca.io documentation URLs and should be removed. Speca is an API design and documentation platform, and its canonical URL format is https://speca.io/[owner]/[api-name]
without query parameters.
Change the link from:
https://speca.io/ticketsauce/ticketsauce-public-api?key=204000d6bda66da78315e721920f43aa#orders
To:
https://speca.io/ticketsauce/ticketsauce-public-api#orders
🤖 Prompt for AI Agents
components/ticketsauce/actions/get-orders/get-orders.mjs around line 6: the
documentation URL in the description includes a temporary query parameter
(?key=...) which should be removed; update the link to
https://speca.io/ticketsauce/ticketsauce-public-api#orders so it follows the
canonical speca.io format without the query string and retains the #orders
fragment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a few comments, some of which may apply to more files. Please check them and let me know if anything is needed.
components/ticketsauce/actions/get-event-details/get-event-details.mjs
Outdated
Show resolved
Hide resolved
components/ticketsauce/actions/get-event-details/get-event-details.mjs
Outdated
Show resolved
Hide resolved
…nents Pulling changes commited by Guilherme during his revie
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…nents Just making sure we're up to date
…iot-rodriguez/sergio_wong_does_pipedream into ticketsauce-components Getting lastest changes from remote
Enhanced prop descriptions: added markdown in date formats, corrected English spelling, etc. Co-authored-by: Guilherme Falcão <[email protected]>
Enhanced prop descriptions: added markdown in date formats, corrected English spelling, etc. Co-authored-by: Guilherme Falcão <[email protected]>
…ails.mjs Enhanced prop descriptions: added markdown in date formats, corrected English spelling, etc. Co-authored-by: Guilherme Falcão <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Enhanced prop descriptions: added markdown in date formats, corrected English spelling, etc. Co-authored-by: Guilherme Falcão <[email protected]>
Enhanced prop descriptions: added markdown in date formats, corrected English spelling, etc. Co-authored-by: Guilherme Falcão <[email protected]>
…ails.mjs Enhanced prop descriptions: added markdown in date formats, corrected English spelling, etc. Co-authored-by: Guilherme Falcão <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
components/ticketsauce/actions/get-event-details/get-event-details.mjs
(1 hunks)components/ticketsauce/actions/get-events/get-events.mjs
(1 hunks)components/ticketsauce/actions/get-order-details/get-order-details.mjs
(1 hunks)components/ticketsauce/actions/get-orders/get-orders.mjs
(1 hunks)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs
(1 hunks)components/ticketsauce/sources/new-event/new-event.mjs
(1 hunks)components/ticketsauce/ticketsauce.app.mjs
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- components/ticketsauce/actions/get-events/get-events.mjs
- components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-17T06:58:24.566Z
Learnt from: sergio-eliot-rodriguez
PR: PipedreamHQ/pipedream#18787
File: components/ticketsauce/ticketsauce.app.mjs:7-30
Timestamp: 2025-10-17T06:58:24.566Z
Learning: The TicketSauce "List of Events" API endpoint (GET /v2/events) does not support pagination and returns all events. Users can filter the data using the available query parameters (partner_id, organization_id, etc.) rather than paginating through results.
Applied to files:
components/ticketsauce/ticketsauce.app.mjs
🧬 Code graph analysis (4)
components/ticketsauce/sources/new-event/new-event.mjs (1)
components/ticketsauce/ticketsauce.app.mjs (1)
events
(37-40)
components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(116-126)
components/ticketsauce/ticketsauce.app.mjs (5)
components/ticketsauce/sources/new-event/new-event.mjs (1)
events
(57-65)components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
params
(57-60)components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(116-126)components/ticketsauce/actions/get-orders/get-orders.mjs (1)
params
(163-178)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (1)
params
(53-56)
components/ticketsauce/actions/get-orders/get-orders.mjs (3)
components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
params
(57-60)components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(116-126)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (1)
params
(53-56)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
🔇 Additional comments (4)
components/ticketsauce/actions/get-order-details/get-order-details.mjs (1)
1-53
: LGTM!The action is well-structured and follows Pipedream component guidelines. It properly uses propDefinitions, chains dependencies correctly (orderId → eventId → partnerId/organizationId), and delegates to the Ticketsauce client.
components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
1-67
: LGTM!The action properly implements boolean conversions for the photos and includePerformers parameters, consistent with the pattern used in get-events.mjs. The propDefinition usage and API delegation are correct.
components/ticketsauce/ticketsauce.app.mjs (1)
1-164
: LGTM!The app file is well-structured with proper propDefinitions and API methods. The implementation correctly handles:
- Pagination for orderId (orders support pagination)
- No pagination for eventId (per learning: List of Events endpoint returns all results)
- Consistent API method patterns with proper $ parameter passing
- Proper OAuth token handling in _makeRequest
Based on learnings
components/ticketsauce/actions/get-orders/get-orders.mjs (1)
162-185
: LGTM!The run() method correctly constructs the params object with appropriate type conversions. Boolean flags (returnQuestionnaires, returnTickets, returnLineItemFees) are properly converted using
parseInt() === 1
, consistent with the pattern used in get-events.mjs and get-event-details.mjs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @sergio-eliot-rodriguez lgtm! I've just added a suggestion. Ready for QA!
components/ticketsauce/actions/get-event-details/get-event-details.mjs
Outdated
Show resolved
Hide resolved
* Add Airweave app with 7 actions for semantic search and collection management. - Search Collection: semantic + keyword search across data sources - List/Create/Get/Delete Collections - List Available Sources - Trigger Source Connection Sync Includes full @airweave/sdk integration, dynamic dropdowns, and comprehensive documentation. * Running ESLint and PNPM, adding annotations * Integrate AirweaveSDKClient with framework details - Added frameworkName and frameworkVersion properties to the AirweaveSDKClient instantiation. - Imported package.json to dynamically set the framework version. * Update airweave.app.mjs --------- Co-authored-by: Guilherme Falcão <[email protected]> Co-authored-by: GTFalcao <[email protected]>
…iot-rodriguez/sergio_wong_does_pipedream into ticketsauce-components syncing upstream with my fork addressing ticketsauce components
…Ins per Jorge review comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 15
♻️ Duplicate comments (1)
components/microsoft_teams/sources/new-channel/new-channel.mjs (1)
8-8
: Same concern as new-team-member: verify version bump necessity.This file also shows only a version bump (0.0.12 → 0.0.13) with no functional changes, and appears unrelated to the TicketSauce-focused PR objectives.
See the review comment on
components/microsoft_teams/sources/new-team-member/new-team-member.mjs
for verification steps.
🧹 Nitpick comments (9)
components/ticketsauce/actions/get-event-details/get-event-details.mjs (1)
38-48
: Consider using a boolean prop type for better UX.The past review suggested using
type: "boolean"
for this prop. Since the API accepts boolean values (as seen in line 58), you can simplify both the prop definition and the conversion logic:Apply this diff:
photos: { - type: "string", + type: "boolean", label: "Photos", description: "Whether or not to return the event's photo gallery records.", optional: true, - default: "0", - options: [ - "0", - "1", - ], + default: false, },Then simplify line 58:
const params = { - photos: parseInt(this.photos) === 1, + photos: this.photos, include_performers: parseInt(this.includePerformers) === 1, };This provides a better user experience (toggle instead of dropdown) and removes unnecessary conversion logic. The same refactor could apply to
includePerformers
if its propDefinition follows a similar pattern.components/airweave/actions/create-collection/create-collection.mjs (1)
16-31
: Add lightweight input sanitization/validation forreadableId
.Fail fast and avoid an API 4xx by trimming and validating the slug shape before calling the SDK. Also trim
name/description
for ergonomics.async run({ $ }) { - const response = await this.airweave.createCollection({ - name: this.name, - readable_id: this.readableId, - description: this.description, - }); + const name = this.name?.trim(); + const readable_id = this.readableId?.trim(); + const description = this.description?.trim(); + if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(readable_id)) { + throw new Error("Readable ID must be lowercase alphanumeric words separated by single hyphens, e.g. 'customer-support-data'."); + } + const response = await this.airweave.createCollection({ + name, + readable_id, + description, + });As per component guidelines.
Also applies to: 33-38
components/airweave/package.json (1)
3-3
: Package hygiene: consider adding license/repository/engines/files.Not required, but improves publishability and tooling.
"author": "Pipedream <[email protected]> (https://pipedream.com/)", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/PipedreamHQ/pipedream" + }, + "engines": { + "node": ">=18" + }, + "files": [ + "airweave.app.mjs", + "actions/", + "sources/" + ], "publishConfig": { "access": "public" }Also applies to: 15-18
components/airweave/actions/list-sources/list-sources.mjs (1)
18-23
: Defensive count in case the SDK returns a non-array shape.Small guard avoids
response.length
throwing if the SDK wraps results.- const count = response.length; - $.export("$summary", `Successfully retrieved ${count} available source connector(s)`); + const count = Array.isArray(response) + ? response.length + : (Array.isArray(response?.data) ? response.data.length : 0); + $.export("$summary", `Successfully retrieved ${count} available source connector(s)`);components/airweave/actions/list-collections/list-collections.mjs (1)
14-33
: Support “fetch all pages” to meet pagination guideline.Add a boolean to auto-paginate; fall back to single page when false. Keeps defaults intact.
props: { airweave, + fetchAll: { + type: "boolean", + label: "Fetch all pages", + description: "If enabled, retrieves all collections by following pagination.", + optional: true, + default: false, + }, skip: { @@ async run({ $ }) { - const response = await this.airweave.listCollections({ - skip: this.skip, - limit: this.limit, - }); + const doFetchAll = !!this.fetchAll; + let response = []; + if (doFetchAll) { + let skip = this.skip ?? 0; + const limit = this.limit ?? 50; + // Defensive loop with cap + for (let i = 0; i < 200; i++) { + const page = await this.airweave.listCollections({ skip, limit }); + const items = Array.isArray(page) ? page : (page?.results || []); + response.push(...items); + if (items.length < limit) break; + skip += items.length; + } + } else { + const page = await this.airweave.listCollections({ skip: this.skip, limit: this.limit }); + response = Array.isArray(page) ? page : (page?.results || []); + } - const count = response.length; + const count = response.length; $.export("$summary", `Successfully retrieved ${count} collection(s)`); return response; },Confirm listCollections returns an array vs an object with results/next cursor. If the SDK exposes total/next, we can switch to that for precision.
Also applies to: 34-44
components/airweave/actions/search-collection/search-collection.mjs (1)
75-79
: Adjust summary for completion vs results.When responseType is “completion”, results may be empty; tailor the summary accordingly.
- const resultCount = response.results?.length || 0; - $.export("$summary", `Successfully searched collection "${this.collectionId}" and found ${resultCount} result(s)`); + const mode = this.responseType || "results"; + if (mode === "completion") { + const hasAnswer = !!(response?.completion || response?.answer); + $.export("$summary", `Generated completion for collection "${this.collectionId}"${hasAnswer ? "" : " (no answer)"}`); + } else { + const resultCount = response.results?.length || 0; + $.export("$summary", `Searched collection "${this.collectionId}" and found ${resultCount} result(s)`); + } return response;Please confirm the SDK uses response_type and offset param names (vs format/skip) and completion field name (completion vs answer).
Also applies to: 34-39
components/airweave/airweave.app.mjs (3)
33-53
: Same pagination hint for sourceConnectionId options.Mirror the hasMore/next token approach here, too, to avoid UI calling without a stop condition.
return { options: connections.map((conn) => ({ label: conn.name || conn.id, value: conn.id, })), - context: { - skip: params.skip + connections.length, - }, + context: { + skip: params.skip + connections.length, + hasMore: connections.length === params.limit, + }, };
93-100
: Cache the SDK client to reduce per-call instantiation overhead.Lightweight but cleaner and cheaper at runtime.
- _client() { - return new AirweaveSDKClient({ - apiKey: this._apiKey(), - baseUrl: this._baseUrl(), - frameworkName: "pipedream", - frameworkVersion: "0.1.0", - }); - }, + _client() { + if (!this._clientInstance) { + this._clientInstance = new AirweaveSDKClient({ + apiKey: this._apiKey(), + baseUrl: this._baseUrl(), + frameworkName: "pipedream", + frameworkVersion: "0.1.0", + }); + } + return this._clientInstance; + },
86-100
: Optional: expose a test() method for connection validation.Useful for “Test” button and clearer auth failures.
methods: { + async test() { + // Lightweight call to validate credentials and base URL + await this.listSources(); + return { ok: true }; + },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (34)
components/airweave/README.md
(1 hunks)components/airweave/actions/create-collection/create-collection.mjs
(1 hunks)components/airweave/actions/delete-collection/delete-collection.mjs
(1 hunks)components/airweave/actions/get-collection/get-collection.mjs
(1 hunks)components/airweave/actions/list-collections/list-collections.mjs
(1 hunks)components/airweave/actions/list-sources/list-sources.mjs
(1 hunks)components/airweave/actions/search-collection/search-collection.mjs
(1 hunks)components/airweave/actions/trigger-sync/trigger-sync.mjs
(1 hunks)components/airweave/airweave.app.mjs
(1 hunks)components/airweave/package.json
(1 hunks)components/coinapi/coinapi.app.mjs
(1 hunks)components/coinapi/package.json
(1 hunks)components/copicake/copicake.app.mjs
(1 hunks)components/copicake/package.json
(1 hunks)components/cronly/cronly.app.mjs
(1 hunks)components/cronly/package.json
(1 hunks)components/microsoft_teams/actions/create-channel/create-channel.mjs
(1 hunks)components/microsoft_teams/actions/list-channels/list-channels.mjs
(1 hunks)components/microsoft_teams/actions/list-shifts/list-shifts.mjs
(1 hunks)components/microsoft_teams/actions/send-channel-message/send-channel-message.mjs
(1 hunks)components/microsoft_teams/actions/send-chat-message/send-chat-message.mjs
(1 hunks)components/microsoft_teams/microsoft_teams.app.mjs
(1 hunks)components/microsoft_teams/package.json
(1 hunks)components/microsoft_teams/sources/new-channel-message/new-channel-message.mjs
(1 hunks)components/microsoft_teams/sources/new-channel/new-channel.mjs
(1 hunks)components/microsoft_teams/sources/new-chat-message/new-chat-message.mjs
(1 hunks)components/microsoft_teams/sources/new-chat/new-chat.mjs
(1 hunks)components/microsoft_teams/sources/new-team-member/new-team-member.mjs
(1 hunks)components/microsoft_teams/sources/new-team/new-team.mjs
(1 hunks)components/ticketsauce/actions/get-event-details/get-event-details.mjs
(1 hunks)components/ticketsauce/actions/get-order-details/get-order-details.mjs
(1 hunks)components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs
(1 hunks)components/topdesk/package.json
(1 hunks)components/topdesk/topdesk.app.mjs
(1 hunks)
✅ Files skipped from review due to trivial changes (9)
- components/microsoft_teams/package.json
- components/microsoft_teams/sources/new-team/new-team.mjs
- components/microsoft_teams/sources/new-channel-message/new-channel-message.mjs
- components/microsoft_teams/sources/new-chat-message/new-chat-message.mjs
- components/airweave/README.md
- components/microsoft_teams/actions/send-channel-message/send-channel-message.mjs
- components/microsoft_teams/actions/list-shifts/list-shifts.mjs
- components/microsoft_teams/actions/create-channel/create-channel.mjs
- components/microsoft_teams/sources/new-chat/new-chat.mjs
🚧 Files skipped from review as they are similar to previous changes (2)
- components/ticketsauce/actions/get-order-details/get-order-details.mjs
- components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs
🧰 Additional context used
🧬 Code graph analysis (8)
components/airweave/actions/list-sources/list-sources.mjs (1)
components/airweave/actions/list-collections/list-collections.mjs (2)
response
(35-38)count
(40-40)
components/ticketsauce/actions/get-event-details/get-event-details.mjs (4)
components/ticketsauce/actions/get-ticket-checkin-ids/get-ticket-checkin-ids.mjs (2)
params
(53-56)response
(58-61)components/ticketsauce/actions/get-events/get-events.mjs (1)
params
(116-126)components/ticketsauce/actions/get-orders/get-orders.mjs (1)
params
(163-178)components/ticketsauce/actions/get-order-details/get-order-details.mjs (1)
response
(49-51)
components/airweave/actions/create-collection/create-collection.mjs (6)
components/airweave/actions/delete-collection/delete-collection.mjs (1)
response
(33-33)components/airweave/actions/get-collection/get-collection.mjs (1)
response
(24-24)components/airweave/actions/list-collections/list-collections.mjs (1)
response
(35-38)components/airweave/actions/list-sources/list-sources.mjs (1)
response
(18-18)components/airweave/actions/search-collection/search-collection.mjs (1)
response
(70-73)components/airweave/actions/trigger-sync/trigger-sync.mjs (1)
response
(34-36)
components/airweave/actions/search-collection/search-collection.mjs (7)
components/airweave/airweave.app.mjs (2)
params
(12-15)params
(35-38)components/airweave/actions/create-collection/create-collection.mjs (1)
response
(34-38)components/airweave/actions/delete-collection/delete-collection.mjs (1)
response
(33-33)components/airweave/actions/get-collection/get-collection.mjs (1)
response
(24-24)components/airweave/actions/list-collections/list-collections.mjs (1)
response
(35-38)components/airweave/actions/list-sources/list-sources.mjs (1)
response
(18-18)components/airweave/actions/trigger-sync/trigger-sync.mjs (1)
response
(34-36)
components/airweave/actions/delete-collection/delete-collection.mjs (2)
components/airweave/actions/create-collection/create-collection.mjs (1)
response
(34-38)components/airweave/actions/get-collection/get-collection.mjs (1)
response
(24-24)
components/airweave/actions/list-collections/list-collections.mjs (1)
components/airweave/actions/list-sources/list-sources.mjs (2)
response
(18-18)count
(20-20)
components/airweave/actions/get-collection/get-collection.mjs (2)
components/airweave/actions/delete-collection/delete-collection.mjs (1)
response
(33-33)components/airweave/actions/search-collection/search-collection.mjs (1)
response
(70-73)
components/airweave/airweave.app.mjs (1)
components/airweave/actions/search-collection/search-collection.mjs (1)
params
(56-60)
🪛 GitHub Actions: Pull Request Checks
components/coinapi/coinapi.app.mjs
[error] 11-11: ESLint: Newline required at end of file but not found. (eol-last)
🪛 GitHub Check: Lint Code Base
components/topdesk/package.json
[failure] 15-15:
Newline required at end of file but not found
components/copicake/copicake.app.mjs
[failure] 11-11:
Newline required at end of file but not found
components/cronly/cronly.app.mjs
[failure] 11-11:
Newline required at end of file but not found
components/topdesk/topdesk.app.mjs
[failure] 11-11:
Newline required at end of file but not found
components/copicake/package.json
[failure] 15-15:
Newline required at end of file but not found
components/coinapi/coinapi.app.mjs
[failure] 11-11:
Newline required at end of file but not found
components/cronly/package.json
[failure] 15-15:
Newline required at end of file but not found
components/coinapi/package.json
[failure] 15-15:
Newline required at end of file but not found
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
- GitHub Check: pnpm publish
🔇 Additional comments (11)
components/microsoft_teams/actions/list-channels/list-channels.mjs (1)
8-8
: LGTM! Version bump is appropriate.The version increment is clean, and the existing code follows best practices with proper pagination and summary emission.
components/microsoft_teams/sources/new-team-member/new-team-member.mjs (1)
8-8
: The review comment is based on incorrect information and should be dismissed.This PR contains only changes to TicketSauce action components (get-event-details, get-order-details, get-ticket-checkin-ids). There are no modifications to any Microsoft Teams files, including
components/microsoft_teams/sources/new-team-member/new-team-member.mjs
. The version "0.0.13" shown in that file is the current state, not a change being made in this PR. The review comment appears to reference a different PR or incorrect file context.Likely an incorrect or invalid review comment.
components/microsoft_teams/microsoft_teams.app.mjs (1)
274-281
: Unable to verify endpoint change claim within codebase.Verification analysis shows:
- No internal callers to
listChannelMessages
found (expected for Pipedream app actions that are exposed to workflow users)- No references to delta endpoints or previous delta implementation found in the microsoft_teams component
- Method signature matches other similar list methods with standard
/messages
paths- No test files exist to validate the endpoint or changes
Since this is a Pipedream app integration, the method is a public API action used by external workflow users rather than being called internally. The claimed change from "delta to regular messages" cannot be confirmed through codebase analysis. You should manually verify:
- Whether this was a breaking change from a previous version
- The impact on existing Pipedream workflows that may depend on this action
- Whether delta updates were previously supported and are now removed
components/ticketsauce/actions/get-event-details/get-event-details.mjs (2)
1-13
: LGTM! Metadata and structure follow conventions.The component key, naming, documentation link, and annotations all follow Pipedream best practices. The read-only hints are appropriate for a GET operation.
56-69
: LGTM! Run method correctly addresses past feedback.The method now properly passes
$
to the API call and exports a descriptive summary, addressing previous review comments. The overall structure and error handling flow are solid.components/microsoft_teams/actions/send-chat-message/send-chat-message.mjs (1)
8-8
: <!-- [scratchpad_start]
[task review_file_1/1 review_segment_1/1 check_justification_3/3]
Final analysis: version field is IDENTICAL between branches.[observations]
- Master branch: version: "0.0.11"
- Current branch: version: "0.0.11"
- git diff: empty (no changes to this file)
- All changed files in PR: no Microsoft Teams files listed
- File is NOT modified in this PR
[analysis]
- The original review comment incorrectly assumes a version bump from 0.0.10 to 0.0.11
- The version is already "0.0.11" in master branch
- This file has zero changes in this PR
- The file content shown in review comment context ("version: 0.0.11") is the final state in MASTER, not a change made by this PR
- Original review was likely based on misleading AI summary or context confusion
[conclusion]
- Review comment is INCORRECT
- There is no version bump to review
- There are no changes to this file in this PR
- The review is flagging a non-existent issue
[tag]
Likely an incorrect or invalid review comment.
components/airweave/actions/create-collection/create-collection.mjs (1)
40-42
: LGTM overall.Good key/name, clear description with docs link, emits summary, and returns API response.
components/airweave/actions/get-collection/get-collection.mjs (1)
15-29
: LGTM.Clear props, correct client call, and useful summary. No issues spotted.
components/airweave/package.json (1)
15-18
: Verify @airweave/sdk 0.1.50 method compatibility before deploying.The version 0.1.50 exists on NPM and is specified correctly in package.json. However, the implementation calls multiple SDK methods (collections.create, collections.delete, collections.list, sourceConnections operations, and sources.list) that should be confirmed available in 0.1.50. The latest version is 0.6.59, but the caret constraint locks to 0.1.x. Verify this version supports all the methods used in components/airweave/airweave.app.mjs before deployment.
components/airweave/actions/trigger-sync/trigger-sync.mjs (2)
16-22
: Note: collectionId not used in run (only for dependent options).This looks intentional to filter sourceConnectionId options. If not required, mark it optional; if required for UX, leave as-is.
33-41
: Guard against duplicate sync jobs on retries: idempotency suggestion is valid, but verify Airweave SDK return format before implementation.The methods
runSourceConnection()
andgetSourceConnectionJobs()
exist inairweave.app.mjs
and are properly exposed. However, their actual return formats are not documented in the codebase—they delegate to the external@airweave/[email protected]
package. Before implementing the suggested guard:
- Confirm
getSourceConnectionJobs()
returns either an array or an object with aresults[]
property- Verify the response from
runSourceConnection()
includesid
andstatus
fields- Consult the Airweave SDK documentation for the exact job status values (the guard assumes
"queued"
and"running"
)The proposed guard logic is defensive and will handle both return formats, but the assumptions about response structure depend on external SDK behavior.
confirmation: { | ||
type: "string", | ||
label: "Confirmation", | ||
description: "Type 'DELETE' to confirm deletion. This action cannot be undone.", | ||
}, | ||
}, | ||
async run({ $ }) { | ||
if (this.confirmation !== "DELETE") { | ||
throw new Error("Please type 'DELETE' to confirm deletion. This action cannot be undone."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Harden confirmation check and summary for 204/empty responses.
DELETE often returns 204. Guard against undefined response
and make confirmation user-proof (trim + case-insensitive).
confirmation: {
type: "string",
label: "Confirmation",
description: "Type 'DELETE' to confirm deletion. This action cannot be undone.",
+ placeholder: "DELETE",
},
...
async run({ $ }) {
- if (this.confirmation !== "DELETE") {
+ if ((this.confirmation ?? "").trim().toUpperCase() !== "DELETE") {
throw new Error("Please type 'DELETE' to confirm deletion. This action cannot be undone.");
}
- const response = await this.airweave.deleteCollection(this.collectionId);
+ const response = await this.airweave.deleteCollection(this.collectionId);
- $.export("$summary", `Successfully deleted collection: ${response.name} (${response.readable_id})`);
+ const name = response?.name ?? this.collectionId;
+ const rid = response?.readable_id ?? this.collectionId;
+ $.export("$summary", `Successfully deleted collection: ${name} (${rid})`);
As per component guidelines.
Also applies to: 33-37
🤖 Prompt for AI Agents
In components/airweave/actions/delete-collection/delete-collection.mjs around
lines 22-31 (and similarly apply to 33-37), the confirmation check and handling
of DELETE responses need hardening: make the confirmation check robust by
trimming whitespace and comparing case-insensitively (e.g., normalize
this.confirmation before validating against "DELETE"), and guard response
processing to accept 204/no-body results by checking for undefined/null response
or empty body before accessing fields — treat a 204 or missing body as a
successful deletion and set the summary accordingly; update error messages and
summary logic to reflect these cases.
recencyBias: { | ||
type: "string", | ||
label: "Recency Bias", | ||
description: "How much to weigh recency vs similarity (0-1). 0 = no recency effect; 1 = rank by recency only", | ||
optional: true, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate recencyBias and avoid passing NaN/out-of-range.
parseFloat may yield NaN; also enforce 0–1 bounds to prevent API errors.
- recencyBias: {
+ recencyBias: {
type: "string",
label: "Recency Bias",
description: "How much to weigh recency vs similarity (0-1). 0 = no recency effect; 1 = rank by recency only",
optional: true,
},
@@
- if (this.recencyBias !== undefined) {
- params.recency_bias = parseFloat(this.recencyBias);
- }
+ if (this.recencyBias !== undefined && this.recencyBias !== "") {
+ const rb = parseFloat(this.recencyBias);
+ if (Number.isNaN(rb) || rb < 0 || rb > 1) {
+ throw new Error(`Invalid recencyBias "${this.recencyBias}". Expected a number between 0 and 1.`);
+ }
+ params.recency_bias = rb;
+ }
Also applies to: 66-68
🤖 Prompt for AI Agents
In components/airweave/actions/search-collection/search-collection.mjs around
lines 48-53 (and also apply same fix to lines 66-68), the recencyBias value is
parsed with parseFloat and may become NaN or outside the allowed 0–1 range;
validate and sanitize it by checking the parsed value is a finite number and
then clamp it to the 0–1 interval (or fallback to a safe default like 0 if
invalid) before passing to the API to avoid NaN or out-of-range errors.
async options({ prevContext }) { | ||
const params = { | ||
skip: prevContext?.skip || 0, | ||
limit: 50, | ||
}; | ||
const collections = await this.listCollections(params); | ||
return { | ||
options: collections.map((collection) => ({ | ||
label: collection.name || collection.readable_id, | ||
value: collection.readable_id, | ||
})), | ||
context: { | ||
skip: params.skip + collections.length, | ||
}, | ||
}; | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Async options pagination: include an explicit “hasMore” (or nextPageToken) to prevent over-fetching.
Current pattern returns context.skip; depending on Pipedream UI, you may also need hasMore or nextPageToken to indicate continuation.
return {
options: collections.map((collection) => ({
label: collection.name || collection.readable_id,
value: collection.readable_id,
})),
- context: {
- skip: params.skip + collections.length,
- },
+ context: {
+ skip: params.skip + collections.length,
+ hasMore: collections.length === params.limit,
+ },
};
🌐 Web query:
Pipedream component prop async options: what is the recommended pagination return shape? Do options() support { options, context:{...} } with hasMore, or { options, nextPageToken }?
💡 Result:
Use the docs’ async-options pagination shape: return an object with an options array and a context containing nextPageToken — e.g. { options, context: { nextPageToken } }. Simple (non-paginated) async options can just return an array. The docs require prevContext-based pagination to use nextPageToken (not hasMore). [1][2]
Sources:
[1] Pipedream Component API — Async Options (pagination) example.
[2] Pipedream Components Guidelines — Async Options / pagination recommendation.
Async options pagination: use nextPageToken
instead of hasMore
per Pipedream docs.
Pipedream's async options pagination requires returning an object with an options array and a context containing nextPageToken. The current implementation should track continuation via nextPageToken
rather than hasMore
.
return {
options: collections.map((collection) => ({
label: collection.name || collection.readable_id,
value: collection.readable_id,
})),
- context: {
- skip: params.skip + collections.length,
- },
+ context: {
+ nextPageToken: collections.length === params.limit ? params.skip + collections.length : undefined,
+ },
};
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In components/airweave/airweave.app.mjs around lines 11–27, the async options
pagination currently returns a context with skip/hasMore; update it to return
nextPageToken per Pipedream docs: compute nextPageToken as the new offset
(params.skip + collections.length) and set it in context when there are more
results, otherwise set nextPageToken to null/undefined to stop pagination; keep
the options array construction the same. Also remove/stop using prevContext.skip
and instead read prevContext.nextPageToken as the incoming offset for subsequent
calls.
authKeys() { | ||
console.log(Object.keys(this.$auth)); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove or replace debug logging in production code.
The authKeys()
method uses console.log()
, which will output to logs in production environments. This appears to be leftover debug code.
Consider one of these approaches:
- Remove the method entirely if it's not needed:
propDefinitions: {},
- methods: {
- // this.$auth contains connected account data
- authKeys() {
- console.log(Object.keys(this.$auth));
- },
- },
+ methods: {},
- Return the keys instead of logging if this method serves a purpose:
- authKeys() {
- console.log(Object.keys(this.$auth));
- },
+ authKeys() {
+ return Object.keys(this.$auth);
+ },
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
authKeys() { | |
console.log(Object.keys(this.$auth)); | |
}, | |
authKeys() { | |
return Object.keys(this.$auth); | |
}, |
🤖 Prompt for AI Agents
In components/coinapi/coinapi.app.mjs around lines 7 to 9, the authKeys() method
contains a console.log call which is debug logging that should not remain in
production; either remove the method entirely if it is unused, or replace the
console.log with a return of Object.keys(this.$auth) so callers can consume the
value (and update any call sites/tests accordingly), ensuring no console.*
statements remain.
authKeys() { | ||
console.log(Object.keys(this.$auth)); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove or replace debug logging in production code.
The authKeys()
method uses console.log()
, which will output to logs in production environments. This appears to be leftover debug code.
Consider one of these approaches:
- Remove the method entirely if it's not needed:
propDefinitions: {},
- methods: {
- // this.$auth contains connected account data
- authKeys() {
- console.log(Object.keys(this.$auth));
- },
- },
+ methods: {},
- Return the keys instead of logging if this method serves a purpose:
- authKeys() {
- console.log(Object.keys(this.$auth));
- },
+ authKeys() {
+ return Object.keys(this.$auth);
+ },
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
authKeys() { | |
console.log(Object.keys(this.$auth)); | |
}, | |
authKeys() { | |
return Object.keys(this.$auth); | |
}, |
🤖 Prompt for AI Agents
In components/topdesk/topdesk.app.mjs around lines 7 to 9, the authKeys() method
currently calls console.log(Object.keys(this.$auth)); which is debug logging
left in production; either remove the authKeys() method entirely if unused, or
change it to return Object.keys(this.$auth) (or otherwise expose the keys via a
non-logging API) and remove the console.log so no debug output is emitted in
production.
Implemented TicketSauce components expressed by user specified in #18366 (which this PR resolves), namely actions
List of Events
Event Details
Orders
Order Details
Ticket Checkin IDs
and source
New Event
which was specified by the app developer via email.
Summary by CodeRabbit